/**
 * Copyright 2006-2015 the original author or authors.
 * <p/>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p/>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p/>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.mybatis.generator.plugins;

import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.xml.Attribute;
import org.mybatis.generator.api.dom.xml.XmlElement;
import org.mybatis.generator.internal.rules.MyRules;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.List;

public class RenameMethodMapperClassPlugin extends PluginAdapter {

    public RenameMethodMapperClassPlugin() {
    }

    private String insertMethodName;
    private String deleteMethodName;
    private String updateMethodName;
    private String selectMethodName;
    private String domainObjectName;


    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }

    @Override
    public void initialized(IntrospectedTable introspectedTable) {

        domainObjectName = introspectedTable.getFullyQualifiedTable()
                .getDomainObjectName();

        selectMethodName = (String) properties.get("selectMethodName");
        deleteMethodName = (String) properties.get("deleteMethodName");
        updateMethodName = (String) properties.get("updateMethodName");
        insertMethodName = (String) properties.get("insertMethodName");

        if (!StringUtility.stringHasValue(domainObjectName)) {
            throw new RuntimeException("domainObjectName is error");
        }

        MyRules myRules = new MyRules(introspectedTable.getRules());
        introspectedTable.setRules(myRules);


        if (selectMethodName != null) {
            introspectedTable.setSelectByPrimaryKeyStatementId(selectMethodName);
        }else {

            introspectedTable.setSelectByPrimaryKeyStatementId(
                    "select" + introspectedTable.getDomianName());
        }

        if (deleteMethodName != null) {
            introspectedTable.setDeleteByPrimaryKeyStatementId(deleteMethodName);
        }else {

            introspectedTable.setDeleteByPrimaryKeyStatementId(
                    "delete" + introspectedTable.getDomianName());
        }

        if (updateMethodName != null) {
            introspectedTable.setUpdateByPrimaryKeySelectiveStatementId(updateMethodName);
        }else {

            introspectedTable.setUpdateByPrimaryKeySelectiveStatementId(
                    "update" + introspectedTable.getDomianName());
        }

        if (insertMethodName != null) {
            introspectedTable.setInsertSelectiveStatementId(insertMethodName);
        }else {

            introspectedTable.setInsertSelectiveStatementId(
                    "insert" + introspectedTable.getDomianName());
        }

        introspectedTable.setBaseResultMapId(
                introspectedTable.getDomianName() + "ResultMap");


    }


    public boolean clientInsertMethodGenerated(Method method, Interface interfaze,
                                               IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean clientUpdateByPrimaryKeyWithoutBLOBsMethodGenerated(
            Method method, Interface interfaze,
            IntrospectedTable introspectedTable) {
        return false;
    }


    public boolean clientInsertSelectiveMethodGenerated(Method method,
                                                        Interface interfaze, IntrospectedTable introspectedTable) {


        setName(method, insertMethodName, "insert", domainObjectName);
        FullyQualifiedJavaType f = new FullyQualifiedJavaType("void");
        method.setReturnType(f);

        return true;
    }

    public boolean clientDeleteByPrimaryKeyMethodGenerated(Method method,
                                                           Interface interfaze, IntrospectedTable introspectedTable) {


        setName(method, deleteMethodName, "delete", domainObjectName);
        FullyQualifiedJavaType f = new FullyQualifiedJavaType("void");
        method.setReturnType(f);

        return true;
    }

    public boolean sqlMapDeleteByPrimaryKeyElementGenerated(XmlElement element,
                                                            IntrospectedTable introspectedTable) {

        return true;
    }

    public boolean clientSelectByPrimaryKeyMethodGenerated(Method method,
                                                           Interface interfaze, IntrospectedTable introspectedTable) {


        setName(method, selectMethodName, "select", domainObjectName);
        FullyQualifiedJavaType f = new FullyQualifiedJavaType("List<" + domainObjectName + ">");
        method.setReturnType(f);

        return true;
    }

    public boolean sqlMapSelectByPrimaryKeyElementGenerated(XmlElement element,
                                                            IntrospectedTable introspectedTable) {
        return true;
    }


    public boolean sqlMapBaseColumnListElementGenerated(XmlElement element,
                                                        IntrospectedTable introspectedTable) {
        Attribute id = null;
        if ((id = element.getAttribute("id")) != null) {

            id.setValue(introspectedTable.getDomianName() + "_Column_List");
            introspectedTable.setBaseColumnListId(introspectedTable.getDomianName() + "_Column_List");
        }

        return true;
    }

    public boolean clientUpdateByPrimaryKeySelectiveMethodGenerated(Method method,
                                                                    Interface interfaze,
                                                                    IntrospectedTable introspectedTable) {

        setName(method, deleteMethodName, "update", domainObjectName);
        FullyQualifiedJavaType f = new FullyQualifiedJavaType("void");
        method.setReturnType(f);

        return true;
    }

    public boolean sqlMapResultMapWithoutBLOBsElementGenerated(
            XmlElement element, IntrospectedTable introspectedTable) {

        return true;
    }

    public boolean sqlMapInsertElementGenerated(XmlElement element,
                                                IntrospectedTable introspectedTable) {
        return false;
    }

    public boolean sqlMapUpdateByPrimaryKeyWithoutBLOBsElementGenerated(
            XmlElement element, IntrospectedTable introspectedTable) {
        return false;
    }


    private void setName(Method method, String name, String type, String domainObjectName) {
        if (StringUtility.stringHasValue(name)) {
            method.setName(name);
        } else {
            method.setName(type + domainObjectName);
        }
    }


}
